<html>
<head>
<style>
  .ace_editor {
    border: 0;
    width: auto;
    height: 100%;
    margin: 0;
    top:0;
    right:0;
    bottom:0;
    left:0;
    z-index: 10000;
    touch-action: none;
  }

  body {
    padding: 0px;
    margin: 0px;
    overflow: hidden;
    -ms-overflow-style: scrollbar;
  }
</style>
</head>
<body>
<textarea id="source">package com.sencha.gxt.explorer.client.extjs_data;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sencha.gxt.explorer.client.extjs.Ext;
import com.sencha.gxt.explorer.client.model.Example.Detail;

import jsinterop.annotations.JsFunction;
import jsinterop.annotations.JsProperty;
import jsinterop.annotations.JsType;

public class ModelDefinitionExtJs implements EntryPoint, IsWidget {

  protected static final int MIN_HEIGHT = 480;
  protected static final int MIN_WIDTH = 640;

  /**
   * Define the Ext Config properties of the object
   */
  @JsType
  public static class PersonConfig {
    @JsProperty
    public String name;
    @JsProperty
    int age = 1;
    @JsProperty
    public String gender;
  }

  /**
   * Define the Ext class Constructor
   */
  @JsFunction
  public static interface Constructor {
    Object onConstructor(Object config);
  }

  /**
   * Define the Ext class
   */
  @JsType
  public static class PersonDefine {
    @JsProperty
    public Object config;

    @JsProperty
    public Constructor constructor;
  }

  /**
   * Define the a Ext Class as a Model with data
   */
  @JsType(isNative = true, namespace = "com.example")
  public static class Person {
    @JsProperty
    public String name;
    @JsProperty
    public int age;
  }

  @Override
  public void onModuleLoad() {
    RootPanel.get().add(asWidget());
  }

  @Override
  public Widget asWidget() {
    FlowPanel fp = new FlowPanel();

    defineUsingJsInterop(fp);
    fp.add(new HTML("<br/>"));
    defineUsingJSNI(fp);

    return fp;
  }

  public void defineUsingJsInterop(FlowPanel fp) {
    PersonConfig config = new PersonConfig();

    PersonDefine personDefine = new PersonDefine();
    personDefine.config = config;

    // Define the model
    // Verify it exists in:
    // Browser Dev Tools: > Ext.data.schema.Schema.instances.default.entities
    Ext.define("com.example.Person", personDefine);

    // Instantiate the model
    Person person = new Person();
    person.name = "Jacky";
    person.age = 35;

    HTML htmlJsInterop = new HTML("JsInterop: name=" + person.name + " age=" + person.age);

    fp.add(htmlJsInterop);
  }

  private void defineUsingJSNI(FlowPanel fp) {
    HTML htmlJSNI = new HTML();
    fp.add(htmlJSNI);

    defineUsingJsni(htmlJSNI.getElement());
  }

  /**
   * JSNI Example
   */
  public native void defineUsingJsni(Element htmlElement) /*-{
    var person = new $wnd.com.example.Person();
    person.name = "Angie";
    person.age = 25;

    var s = "JSNI: name=" + person.name + " age=" + person.age;
    htmlElement.innerHTML = s;
  }-*/;

}
</textarea>

<script src="../../samples/ace/ace.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
  var type = "{type}";
  if (type == ("{" + "type}")) {
    // something went wrong, use java as default
    type = "java";
  }
  var editor = ace.edit("source");
  var mode = "ace/mode/" + type;
  var theme = "ace/theme/chrome";
  var readOnly = true;
  editor.getSession().setMode(mode);
  editor.getSession().setUseWorker(false);
  editor.setTheme(theme);
  editor.setShowPrintMargin(false);
  editor.renderer.setShowGutter(true);
  editor.setHighlightActiveLine(false);
  editor.setDisplayIndentGuides(true);
  editor.setReadOnly(readOnly);
  editor.renderer.setPadding(10);
  editor.renderer.setScrollMargin(10, 10, 0, 0);
  editor.getSession().setOptions({
    tabSize: 8,
    useSoftTabs: true,
    useWrapMode: false,
  });
</script>
</body>
</html>